package com.quaidi.smartlocker.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quaidi.smartlocker.entity.LockerCompartment;
import com.quaidi.smartlocker.mapper.LockerCompartmentMapper;
import com.quaidi.smartlocker.service.LockerCompartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 智能柜格Service实现类
 * 
 * @author QuaiDi
 * @since 2025-08-26
 */
@Service
public class LockerCompartmentServiceImpl extends ServiceImpl<LockerCompartmentMapper, LockerCompartment> implements LockerCompartmentService {

    @Autowired
    private LockerCompartmentMapper lockerCompartmentMapper;

    @Override
    @Transactional
    public LockerCompartment allocateCompartment(String packageSize) {
        // 查找可用的柜格
        LockerCompartment compartment = lockerCompartmentMapper.findAvailableCompartmentBySize(packageSize);
        if (compartment != null) {
            // 更新柜格状态为占用
            compartment.setCompartmentStatus("OCCUPIED");
            lockerCompartmentMapper.updateById(compartment);
        }
        return compartment;
    }

    @Override
    @Transactional
    public boolean releaseCompartment(Long compartmentId) {
        LockerCompartment compartment = lockerCompartmentMapper.selectById(compartmentId);
        if (compartment != null && "OCCUPIED".equals(compartment.getCompartmentStatus())) {
            compartment.setCompartmentStatus("AVAILABLE");
            return lockerCompartmentMapper.updateById(compartment) > 0;
        }
        return false;
    }

    @Override
    public Map<String, Long> getCompartmentStatusStatistics() {
        List<LockerCompartment> allCompartments = lockerCompartmentMapper.selectList(null);
        Map<String, Long> statistics = new HashMap<>();
        
        // 统计各状态的柜格数量
        statistics.put("AVAILABLE", allCompartments.stream()
                .filter(c -> "AVAILABLE".equals(c.getCompartmentStatus()))
                .count());
        statistics.put("OCCUPIED", allCompartments.stream()
                .filter(c -> "OCCUPIED".equals(c.getCompartmentStatus()))
                .count());
        statistics.put("MAINTENANCE", allCompartments.stream()
                .filter(c -> "MAINTENANCE".equals(c.getCompartmentStatus()))
                .count());
        statistics.put("TOTAL", (long) allCompartments.size());
        
        return statistics;
    }

    @Override
    public Map<Integer, List<LockerCompartment>> getCompartmentsByFloor() {
        List<LockerCompartment> allCompartments = lockerCompartmentMapper.findAllGroupByFloor();
        return allCompartments.stream()
                .collect(Collectors.groupingBy(LockerCompartment::getFloorNumber));
    }

    @Override
    public boolean isCompartmentCodeUnique(String compartmentCode) {
        if (compartmentCode == null || compartmentCode.trim().isEmpty()) {
            return false;
        }
        
        LambdaQueryWrapper<LockerCompartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LockerCompartment::getCompartmentCode, compartmentCode.trim());
        return this.count(wrapper) == 0;
    }

    @Override
    public boolean isCompartmentCodeUniqueForUpdate(String compartmentCode, Long excludeId) {
        if (compartmentCode == null || compartmentCode.trim().isEmpty()) {
            return false;
        }
        
        LambdaQueryWrapper<LockerCompartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LockerCompartment::getCompartmentCode, compartmentCode.trim())
               .ne(LockerCompartment::getId, excludeId);
        return this.count(wrapper) == 0;
    }

    @Override
    @Transactional
    public boolean createCompartmentWithValidation(LockerCompartment compartment) {
        // 验证必填字段
        if (compartment.getCompartmentCode() == null || compartment.getCompartmentCode().trim().isEmpty()) {
            throw new RuntimeException("柜格编号不能为空");
        }
        if (compartment.getCompartmentSize() == null || compartment.getCompartmentSize().trim().isEmpty()) {
            throw new RuntimeException("柜格尺寸不能为空");
        }
        if (compartment.getFloorNumber() == null) {
            throw new RuntimeException("楼层不能为空");
        }
        if (compartment.getPositionNumber() == null) {
            throw new RuntimeException("位置编号不能为空");
        }

        // 验证柜格编号唯一性
        if (!isCompartmentCodeUnique(compartment.getCompartmentCode())) {
            throw new RuntimeException("柜格编号已存在，请使用其他编号");
        }

        // 设置默认值
        if (compartment.getCompartmentStatus() == null || compartment.getCompartmentStatus().trim().isEmpty()) {
            compartment.setCompartmentStatus("AVAILABLE");
        }
        if (compartment.getLockerId() == null || compartment.getLockerId().trim().isEmpty()) {
            compartment.setLockerId("LOCKER_001");
        }

        // 清理空格
        compartment.setCompartmentCode(compartment.getCompartmentCode().trim());
        compartment.setCompartmentSize(compartment.getCompartmentSize().trim());

        return this.save(compartment);
    }

    @Override
    @Transactional
    public boolean updateCompartmentWithValidation(Long id, LockerCompartment compartment) {
        // 检查柜格是否存在
        LockerCompartment existing = this.getById(id);
        if (existing == null) {
            throw new RuntimeException("柜格不存在");
        }

        // 如果修改了柜格编号，验证新编号的唯一性
        if (compartment.getCompartmentCode() != null && 
            !compartment.getCompartmentCode().trim().equals(existing.getCompartmentCode())) {
            
            if (!isCompartmentCodeUniqueForUpdate(compartment.getCompartmentCode(), id)) {
                throw new RuntimeException("柜格编号已存在，请使用其他编号");
            }
            
            // 清理空格
            compartment.setCompartmentCode(compartment.getCompartmentCode().trim());
        }

        // 清理其他字段的空格
        if (compartment.getCompartmentSize() != null) {
            compartment.setCompartmentSize(compartment.getCompartmentSize().trim());
        }

        // 设置ID并更新
        compartment.setId(id);
        return this.updateById(compartment);
    }
}